#include "CalculadorGanacias.h"

#include "ListaPrincipal.h"
#include "Lista.h"
#include "PalabraConFrecuencias.h"

CalculadorGanacias::CalculadorGanacias(ListaPrincipal* matriz) {
	this->matriz = matriz;
}

CalculadorGanacias::~CalculadorGanacias() {

}

double CalculadorGanacias::calcularEntropia(double a, double b) {

	if (a <= 0.0 || b <= 0.0) {
		return 0.0;
	}

	double total = a + b;
	double resultado = -(a/total)*log(a/total) - (b/total)*log(b/total);

	// paso el resultado a base 2.
	resultado = resultado/log(2);

	return resultado;
}

double CalculadorGanacias::calcularGanancia(Lista<int> *idParrafos, PalabraConFrecuencias* columna) {

	double cantidadMarx = 0.0, cantidadWeber = 0.0, numeroParrafo = 0.0;
	double marxEsta = 0.0, marxNoEsta = 0.0, weberEsta = 0.0, weberNoEsta = 0.0;

	double ganancia = 0.0;

	IteradorLista<FrecuenciaParrafo*> it = columna->getListaFrecuencias()->iterador();
	while(it.tieneSiguiente()){

		numeroParrafo++;

		FrecuenciaParrafo* fp = it.siguiente();

		if(existeParrafo(numeroParrafo, idParrafos)){

			if(fp->getAutor() == "M"){
				cantidadMarx += 1.0;
				if(fp->getContador() > 0)
					marxEsta += 1.0;
				else
					marxNoEsta += 1.0;
			}else if(fp->getAutor() == "W"){
				cantidadWeber += 1.0;
				if(fp->getContador() > 0)
					weberEsta += 1.0;
				else
					weberNoEsta += 1.0;
			}

		}
	}

	double total = cantidadMarx + cantidadWeber;

	double a = calcularEntropia(cantidadMarx, cantidadWeber)*100;
	double b = (cantidadMarx/total)*calcularEntropia(marxEsta,marxNoEsta)*100;
	double c = (cantidadWeber/total)*calcularEntropia(weberEsta,weberNoEsta)*100;

	ganancia = a - b - c;

	return ganancia;
}

string CalculadorGanacias::devolverMejorPalabra(Lista<int> *idParrafos) {

	IteradorLista<PalabraConFrecuencias*> it = matriz->getLista()->iterador();

	PalabraConFrecuencias* mejorPalabra = NULL;
	double mejorGanancia = 0.0;

	while(it.tieneSiguiente()) {

		PalabraConFrecuencias* actual = it.siguiente();

		if(!actual->getMarcada()) {
			double ganancia = calcularGanancia(idParrafos, actual);
			mejorGanancia = ganancia;
			mejorPalabra = actual;
			break;
		}
	}

	while(it.tieneSiguiente()) {
		PalabraConFrecuencias* actual = it.siguiente();

		if(!actual->getMarcada()){
			double ganancia = calcularGanancia(idParrafos, actual);

			if(ganancia > mejorGanancia){
				mejorGanancia = ganancia;
				mejorPalabra = actual;
			}
		}
	}

	if (mejorPalabra != NULL) {
		mejorPalabra->setMarcada(true);
		return mejorPalabra->getPalabra();
	}

	cerr << "Error: No se encontraron palabras sin marcar" << endl;

	return "";
}

bool CalculadorGanacias::existeParrafo(int id, Lista<int> *idParrafos) {

	IteradorLista<int> it = idParrafos->iterador();

	while (it.tieneSiguiente()) {
		int actual = it.siguiente();

		if (actual == id) {
			return true;
		}
	}

	return false;
}
